<template>
  <el-dialog
    title="订单发货"
    width="40%"
    top="10vh"
    center
    :close-on-click-modal="false"
    :visible.sync="visible"
    @close="visible = !visible"
  >
    <div>
      <PageTable :data="dataSource" :columns="columns" />
    </div>

    <el-alert
      v-if="rowData.expressType === 2"
      class="mt-20"
      title="注：此订单已同步第三方平台订单及物流状态，当平台进行自主发货或修改物流，将不同步第三方平台数据"
      type="warning"
      show-icon
    >
    </el-alert>

    <el-form v-loading="loading" class="mt-30" ref="elForm" :model="formData" label-width="100px">
      <div v-for="(ele, index) in formData.orderShipments" :key="index">
        <el-form-item
          label="快递公司："
          :prop="'orderShipments.' + index + '.companyId'"
          :rules="[
            {
              required: true,
              message: '请选择选择快递公司',
              trigger: 'change'
            }
          ]"
        >
          <ScrollSelect
            placeholder="请选择选择快递公司"
            :selected-value="ele.companyId"
            :get-list-methods="getListMethods"
            :get-list-format="getListFormat"
            :page-sizes="pageSize"
            :clearable="true"
            search-key="name"
            @selectedChange="selectedChange($event, index)"
          />
        </el-form-item>
        <el-form-item
          label="快递单号："
          :prop="'orderShipments.' + index + '.expressNo'"
          :rules="[
            {
              required: true,
              message: '请输入快递单号',
              trigger: ['blur', 'change']
            },
            {
              pattern: /^[A-Za-z0-9]{8,22}$/,
              message: '快递单号8-22位，支持数字和英文字符输入',
              trigger: ['blur', 'change']
            }
          ]"
        >
          <el-input v-model="ele.expressNo" placeholder="请输入快递单号" />
        </el-form-item>
        <el-form-item
          v-if="formData.orderShipments.length > 1"
          :prop="'orderShipments.' + index + '.expressNum'"
          :label="`包裹${index + 1}`"
          :rules="[
            {
              required: true,
              message: '请输入数量',
              trigger: ['blur', 'change']
            },
            {
              pattern: REGEX_POSITIVE_INTEGER,
              message: '请输入正整数',
              trigger: ['blur', 'change']
            }
          ]"
        >
          <span>共计</span>
          <el-input-number class="ml-5 mr-5" v-model="ele.expressNum" :step="1"></el-input-number>
          <span>件商品</span>
          <PopConfirm text="确认删除该运单吗？" :confirm="() => deleteSports(index)">
            <el-button class="ml-10" type="text">删除</el-button>
          </PopConfirm>
        </el-form-item>
      </div>

      <div style="margin-left: 100px">
        <p class="ft-12" style="color: #999999">
          *请仔细填写物流公司及物流单号，发货后72小时内仅支持做一次更正，逾期不可修改
        </p>
        <div class="mt-10">
          <span v-if="orderNum === 1" class="ft-14">一种包裹按数量拆分多包裹发货</span>
          <PopConfirm
            v-if="orderNum > 1"
            text="确认全部清空运单吗？"
            :confirm="() => deleteAllSports()"
          >
            <el-button class="ml-10" type="text">全部清空</el-button>
          </PopConfirm>
          <el-button class="ml-10" type="text" @click="addSports">{{ addOrderText }}</el-button>
          <p v-if="orderNum > 1" class="ft-14">
            每个包裹必须填写商品数量且包裹数量总和等于该商品总数量才可以发货
          </p>
        </div>
      </div>

      <el-form-item class="text-center mt-20" label-width="0">
        <el-button @click="resetForm"> 取消 </el-button>
        <el-button type="primary" @click="submitForm"> 确认 </el-button>
      </el-form-item>
    </el-form>
  </el-dialog>
</template>

<script>
import _ from 'lodash'
import { REGEX_POSITIVE_INTEGER } from '@/utils/validate'
export default {
  name: 'OrderShipPopup',
  props: {
    rowData: Object,
    dialogVisible: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      loading: false,
      goodsTotalNum: 0, // 单包裹统计商品数量
      formData: {
        orderShipments: [
          {
            companyCode: '',
            companyId: '',
            companyName: '',
            expressNo: '',
            expressNum: ''
          }
        ]
      },
      expressCompany: [],
      columns: [
        {
          label: '商品',
          render: (h, { row }) => {
            return (
              <div class="flex">
                <el-image
                  style={'width: 50px;height: 50px;'}
                  src={row.goodsMainGraph}
                  previewSrcList={[row.goodsMainGraph]}
                />
                <div class=" flex flex-col justify-between ml-5">
                  <p style="color: #293c66">{row.goodsName}</p>
                  <p>{row.goodsSkuName}</p>
                </div>
              </div>
            )
          }
        },
        {
          label: '数量',
          render: (h, { row }) => {
            return <div>x{row.goodsNum}</div>
          }
        }
      ],
      dataSource: [],
      expressList: [],
      getListMethods: params => {
        return this.queryExpressCompany(params)
      },
      getListFormat: (list = []) => {
        // 下拉框数据格式
        return list.map(({ name, id }) => ({
          label: name,
          value: id
        }))
      },
      pageSize: 10
    }
  },
  computed: {
    visible: {
      get() {
        return this.dialogVisible
      },
      set(val) {
        this.$emit('update:dialogVisible', val)
      }
    },
    // 正整数
    REGEX_POSITIVE_INTEGER() {
      return REGEX_POSITIVE_INTEGER
    },
    // 运单数量
    orderNum: {
      get() {
        return this.formData.orderShipments?.length
      },
      set(val) {
        return val
      }
    },
    addOrderText() {
      return this.orderNum > 1 ? '继续新增' : '新增运单'
    }
  },
  created() {
    this.getGoodsInfo()
    this.getExpressInfo()
  },
  methods: {
    // 获取快递公司
    async queryExpressCompany(params) {
      const {
        data: { records }
      } = await this.$http.express.companyApi.queryExpressCompany({ params })
      this.expressCompany = [...this.expressCompany, ...records]
      return records
    },
    // 获取物流信息
    getExpressInfo() {
      if (this.rowData.type !== 'update') return
      this.loading = true
      let data = []
      this.pageSize = 5000 // 回显快递公司，查所有
      this.rowData.expressIdList.forEach((ele, index) => {
        data[index] = new Promise(reslove => {
          this.$http.order.orderApi.getExpressInfo(ele).then(res => {
            reslove({
              companyId: res.data.companyId,
              companyCode: res.data.companyCode,
              companyName: res.data.companyName,
              expressNo: res.data.expressNo,
              expressNum: res.data.expressNum
            })
          })
        })
      })
      Promise.all([...data]).then(res => {
        this.formData.orderShipments = res

        // 单包裹发货记录商品数量
        if (this.formData.orderShipments.length === 1) {
          this.goodsTotalNum = this.formData.orderShipments[0]?.expressNum
        }
        this.loading = false
      })
    },
    // 新增运单
    addSports() {
      // 修改运单
      if (this.rowData.type === 'update') {
        // 新增就减少1
        this.goodsTotalNum -= 1
        if (this.goodsTotalNum <= 0)
          return this.$message.error('包裹内商品总数已等于订单下单数量！')

        // 新增运单每次减少数组第一个快递数量
        let orderShipments = this.$lodash
          .cloneDeep(this.formData.orderShipments)
          .map((item, index) => {
            if (index === 0) {
              item.expressNum = this.goodsTotalNum
            }
            return item
          })

        this.formData.orderShipments = [
          ...orderShipments,
          {
            companyCode: '',
            companyId: '',
            companyName: '',
            expressNo: '',
            expressNum: 1
          }
        ]
      } else {
        let goodsNum = this.totalOrderNum(this.dataSource, 'goodsNum')
        let totalNum = this.totalOrderNum(this.formData.orderShipments, 'expressNum')
        if (totalNum >= goodsNum) return this.$message.error('包裹内商品总数已等于订单下单数量！')
        this.formData.orderShipments = [
          ...this.formData.orderShipments,
          {
            companyCode: '',
            companyId: '',
            companyName: '',
            expressNo: '',
            expressNum: ''
          }
        ]
      }
    },
    // 删除运单
    deleteSports(currentIndex) {
      this.formData.orderShipments = this.formData.orderShipments.filter(
        (item, index) => index !== currentIndex
      )

      // 编辑运单，删除一个运单后，运单数加1
      if (this.rowData.type === 'update') {
        this.goodsTotalNum += 1
      }
    },
    // 清空运单
    deleteAllSports() {
      this.formData.orderShipments = [
        {
          companyCode: '',
          companyId: '',
          companyName: '',
          expressNo: '',
          expressNum: this.dataSource[0]?.goodsNum
        }
      ]
      if (this.formData.orderShipments.length === 1) {
        this.goodsTotalNum = this.formData.orderShipments[0]?.expressNum
      }
    },
    // 监听快递公司
    selectedChange(val, index) {
      this.$set(this.formData.orderShipments, index, {
        ...this.formData.orderShipments[index],
        companyId: val
      })
      // this.formData.orderShipments[index].companyId = val
    },
    // 获取订单信息
    getGoodsInfo() {
      this.dataSource = this.rowData.detailList
    },
    // 发货
    deliverOrderShip: _.debounce(async function () {
      const params = {
        orderNo: this.rowData.orderNo
      }
      // 深拷贝
      const data = this.$lodash.cloneDeep(this.formData.orderShipments)
      const list = data.map(item => {
        return {
          companyCode: this.expressCompany.find(ele => ele.id == item.companyId)?.code,
          companyId: item.companyId,
          companyName: this.expressCompany.find(ele => ele.id == item.companyId)?.name,
          expressNo: item.expressNo,
          // 单包裹取子订单的第一项
          expressNum:
            this.orderNum > 1 ? item.expressNum : this.totalOrderNum(this.dataSource, 'goodsNum')
        }
      })
      params.orderShipments = list

      //  deliverOrderShip: 订单发货 updateExpress: 修改物流
      let httpKey = this.rowData.type === 'update' ? 'updateExpress' : 'deliverOrderShip'
      let message = this.rowData.type === 'update' ? '修改成功！' : '发货成功！'
      const { status, msg } = await this.$http.order.orderApi[httpKey](params)
      if (status === 200) {
        this.$message.success(message)
        this.visible = false
        this.$emit('update')
      } else {
        this.$message.error(msg)
      }
    }, 200),
    // 计算订单总数
    totalOrderNum(data, key) {
      return data.reduce((prev, next) => {
        return prev + next[key]
      }, 0)
    },
    submitForm() {
      this.$refs['elForm'].validate(async valid => {
        if (!valid) return
        // 计算总运单数量和商品信息数量比较。相等则可发货

        // 默认为一个包裹时要取商品里面的数量
        let currentTotal
        if (this.formData.orderShipments.length === 1) {
          currentTotal = this.totalOrderNum(this.dataSource, 'goodsNum')
        } else {
          currentTotal = this.totalOrderNum(this.formData.orderShipments, 'expressNum')
        }
        const goodsTotal = this.totalOrderNum(this.dataSource, 'goodsNum')

        if (currentTotal !== goodsTotal) {
          return this.$message.error('包裹数量总和等于该商品总数量才可以发货！')
        }
        this.deliverOrderShip()
      })
    },
    resetForm() {
      this.visible = false
      this.$refs['elForm'].resetFields()
    }
  }
}
</script>
